package com.itheima.health.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.OrderSettingDao;
import com.itheima.health.exception.MyException;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Order;
import com.itheima.health.pojo.OrderSetting;
import com.itheima.health.service.OrderService;
import com.itheima.health.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = OrderService.class)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderSettingDao orderSettingDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private MemberDao memberDao;

    /**
     * 实现预约提交
     * @param paraMap
     * @return
     * @throws MyException
     */
    @Override
    @Transactional//添加 事务
    public Integer submit(Map<String, String> paraMap) {

        //通过日期查询预约设置表
        String orderDateString = paraMap.get("orderDate");

        //扩大orderDate范围
        Date orderDate = null;

        //日期应该在controller做验证后才进来的service
        try {
            //把日期进行格式化
            orderDate = DateUtils.parseString2Date(orderDateString);
        } catch (Exception e) {

            //抛出异常
            throw new MyException("预约日期格式不正确");
        }
        //获取通过日期查询预约的设置表
        OrderSetting orderSetting = orderSettingDao.findByOrderDate(orderDate);

        //进行判断
        if (null == orderSetting){

            //为空，就报错，则代表当日没有可预约人数，并显示提示信息
            throw new MyException("当日没有可预约人数，请选择其他日期进行预约！");
        }
        //不为空，则判断当日是否已约满
        if (orderSetting.getReservations() >= orderSetting.getNumber()){

            //已预约人数>=可预约人数，则代表不能预约
            throw new MyException("所选日期预约已满，请选择其它日期");
        }
        //查看是否构成重复预约查询条件
        //新建订单
        Order order = new Order();

        //设置订单
        order.setSetmealId(Integer.valueOf(paraMap.get("setmealId")));

        order.setOrderDate(orderDate);

        //获取手机号码
        String telephone = paraMap.get("telephone");

        //通过手机号查询该手机是否已经注册过，是否为会员
        Member member = memberDao.findByTelephone(telephone);

        //进行判断
        if (member == null){

            //如果为空，说明没存在，则添加新会员，插入记录时要返回主键
             member = new Member();

            //插入新会员信息
            member.setPhoneNumber(telephone);
            member.setRegTime(new Date());
            member.setRemark("微信预约注册");
            String idCardNo = paraMap.get("idCard");
            member.setPassword(idCardNo.substring(idCardNo.length()-6));
            member.setIdCard(idCardNo);
            member.setSex(paraMap.get("sex"));
            member.setName(paraMap.get("name"));
            memberDao.add(member);
            order.setMemberId(member.getId());

        }else {
            //如果该手机号已经注册过,则获取会员id
            Integer memberId = member.getId();

            //判断该会员是否重复预约
            order.setMemberId(memberId);

            //通过预约日期，会员id,套餐id查询t_order
            List<Order> orderList = orderDao.findByCondition(order);

            //存在，则报错，已经预约过，请勿重复预约
            if (null != orderList && orderList.size() > 0){

                //如果预约列表不为空，并且长度大于0，则代表已预约过
                throw new MyException("您已经预约过了，请忽重复预约");
            }
        }
        //更新已预约人数
        int count = orderSettingDao.editReservationsByOrderDate(orderSetting);

        //并发，加分布式锁（利用数据库的行锁） where reservations>number
        //如果更新失败，则返回0，报错，预约已满，请选择其它日期
        if (count == 0){

            throw new MyException("预约已满，请选择其它日期");
        }
        //如果更新成功，mybatis则会返回1
        //添加订单信息，返回主键
        order.setOrderStatus(Order.ORDERSTATUS_NO);

        order.setOrderType(paraMap.get("orderType"));

        //添加订单
        orderDao.add(order);

        //- 返回订单的id给controller
        return order.getId();
    }

    /**
     * 通过id查询订单信息，预约成功提示
     * @param id
     * @return
     */
    @Override
    public Map<String, String> findOrderDetailById(int id) {

        return orderDao.findById4Detail(id);
    }
}
